﻿using Vboot.Core.Module.Bpm;

namespace Vboot.App.My;

//DEMO服务
public class MyDemoMainService : BaseMainService<MyDemoMain>, ITransient
{
    public async Task<string> Insertx(MyDemoMain main)
    {
        main.state = "20";
        main.uptim = DateTime.Now;
        await Insert(main);
        Zbpm zbpm = main.zbpm;
        zbpm.proid = main.id;
        zbpm.prona = main.name;
        zbpm.haman = main.crmid;
        zbpm.tmpid = main.protd;
        Znode znode = await _procService.Start(zbpm);
        if (znode.facno == "N3")
        {
            main.state = "30";
            await UpdateAsync(main);
        }
        return main.id;
    }
    
    //级联新增
    public async Task<string> Insert(MyDemoMain main)
    {
        main.id = YitIdHelper.NextId() + "";
        main.crmid = XuserUtil.getUserId();
        await repo.Context.InsertNav(main)
            .Include(it => it.vimen)
            .Include(it => it.edmen)
            .Include(it => it.items)
            .Include(it => it.atts)
            .ExecuteCommandAsync();
        return main.id;
    }
    
    public async Task<string> Updatex(MyDemoMain main)
    {
        await Update(main);
        if (main.zbpm.opkey == "pass")
        {
            Znode znode =await _procService.HandlerPass(main.zbpm);
            if (znode.facno == "N3")
            {
                main.state = "30";
                await UpdateAsync(main);
            }
        }
        else if (main.zbpm.opkey == "refuse")
        {
            await _procService.HandlerRefuse(main.zbpm);
        }
        return main.id;
    }

    //级联修改
    public async Task<string> Update(MyDemoMain main)
    {
        main.upmid = XuserUtil.getUserId();
        await repo.Context.UpdateNav(main)
            .Include(it => it.vimen)
            .Include(it => it.edmen)
            .Include(it => it.items)
            .Include(it => it.atts)
            .ExecuteCommandAsync();
        return main.id;
    }

    //级联删除
    public async Task Delete(string ids)
    {
        var idArr = ids.Split(",");
        for (int i = 0; i < idArr.Length; i++)
        {
            var id = idArr[i];
            await repo.Context.DeleteNav<MyDemoMain>(it => it.id == id)
                .Include(it => it.vimen, new DeleteNavOptions() {ManyToManyIsDeleteA = true})
                .Include(it => it.edmen, new DeleteNavOptions() {ManyToManyIsDeleteA = true})
                .Include(it => it.items)
                .Include(it => it.atts)
                .ExecuteCommandAsync();
        }
    }

    //级联查询
    public async Task<MyDemoMain> Select(String id)
    {
        var main = await repo.Context.Queryable<MyDemoMain>()
            .Where(it => it.id == id)
            .Includes(t => t.crman)
            .Includes(t => t.upman)
            .Includes(t => t.vimen)
            .Includes(t => t.edmen)
            .Includes(t => t.items.OrderBy(b => b.ornum).ToList())
            .Includes(t => t.atts.OrderBy(b => b.ornum).ToList())
            .Includes(t => t.opman)
            .SingleAsync();
        return main;
    }


    //原来老的方式 ：新增
    public async Task<string> Inserty(MyDemoMain main)
    {
        main.id = YitIdHelper.NextId() + "";
        main.crmid = XuserUtil.getUserId();
        await repo.Context.Insertable(main)
            .AddSubList(it => it.items.First().maiid)
            .AddSubList(it => it.atts.First().busid)
            .ExecuteCommandAsync();
        var viewers = new List<MyDemoViman>();
        foreach (var viewer in main.vimen)
        {
            viewers.Add(new MyDemoViman {mid = main.id, oid = viewer.id});
        }

        var editors = new List<MyDemoEdman>();
        foreach (var editor in main.edmen)
        {
            editors.Add(new MyDemoEdman {mid = main.id, oid = editor.id});
        }

        await repo.Context.Insertable(viewers).ExecuteCommandAsync();
        await repo.Context.Insertable(editors).ExecuteCommandAsync();
        return main.id;
    }

    //原来老的方式 ：修改
    public async Task<string> Updatey(MyDemoMain main)
    {
        main.upmid = XuserUtil.getUserId();
        var viewers = new List<MyDemoViman>();
        if (main.vimen != null)
        {
            foreach (var viewer in main.vimen)
            {
                viewers.Add(new MyDemoViman {mid = main.id, oid = viewer.id});
            }
        }

        var editors = new List<MyDemoEdman>();
        if (main.edmen != null)
        {
            foreach (var editor in main.edmen)
            {
                editors.Add(new MyDemoEdman {mid = main.id, oid = editor.id});
            }
        }

        await base.UpdateAsync(main);
        await repo.Context.Deleteable<MyDemoViman>().Where(it => it.mid == main.id).ExecuteCommandAsync();
        await repo.Context.Deleteable<MyDemoEdman>().Where(it => it.mid == main.id).ExecuteCommandAsync();
        await repo.Context.Insertable(viewers).ExecuteCommandAsync();
        await repo.Context.Insertable(editors).ExecuteCommandAsync();


        //比对数据库中的contact,插入页面上新增的，更新页面上修改的，删除页面上删除的
        List<MyDemoItem> list = await repo.Context.Queryable<MyDemoItem>()
            .Where(t => t.maiid == main.id).ToListAsync();
        List<MyDemoItem> insertList = new List<MyDemoItem>();
        List<MyDemoItem> updateList = new List<MyDemoItem>();
        List<MyDemoItem> deleteList = new List<MyDemoItem>();
        for (int i = 0; i < list.Count; i++)
        {
            bool flag = false;
            for (int j = 0; j < main.items.Count; j++)
            {
                if (main.items[j].id == list[i].id)
                {
                    flag = true;
                    updateList.Add(main.items[j]); //找到相同的则更新
                    break;
                }
            }

            if (!flag)
            {
                deleteList.Add(list[i]);
            }
        }

        for (int j = 0; j < main.items.Count; j++)
        {
            bool flag = false;
            for (int i = 0; i < list.Count; i++)
            {
                if (main.items[j].id == list[i].id)
                {
                    flag = true;
                    break;
                }
            }

            if (!flag)
            {
                insertList.Add(main.items[j]);
            }
        }

        await repo.Context.Deleteable(deleteList).ExecuteCommandAsync();
        await repo.Context.Updateable(updateList).ExecuteCommandAsync();
        await repo.Context.Insertable(insertList).ExecuteCommandAsync();


        //比对数据库中的att,插入页面上新增的，更新页面上修改的，删除页面上删除的
        List<MyDemoAtt> attList = await repo.Context.Queryable<MyDemoAtt>()
            .Where(t => t.busid == main.id).ToListAsync();
        List<MyDemoAtt> attInsertList = new List<MyDemoAtt>();
        List<MyDemoAtt> attUpdateList = new List<MyDemoAtt>();
        List<MyDemoAtt> attDeleteList = new List<MyDemoAtt>();
        for (int i = 0; i < attList.Count; i++)
        {
            bool flag = false;
            for (int j = 0; j < main.atts.Count; j++)
            {
                if (main.atts[j].id == attList[i].id)
                {
                    flag = true;
                    attUpdateList.Add(main.atts[j]); //找到相同的则更新
                    break;
                }
            }

            if (!flag)
            {
                attDeleteList.Add(attList[i]);
            }
        }

        for (int j = 0; j < main.atts.Count; j++)
        {
            bool flag = false;
            for (int i = 0; i < attList.Count; i++)
            {
                if (main.atts[j].id == attList[i].id)
                {
                    flag = true;
                    break;
                }
            }

            if (!flag)
            {
                attInsertList.Add(main.atts[j]);
            }
        }

        await repo.Context.Deleteable(attDeleteList).ExecuteCommandAsync();
        await repo.Context.Updateable(attUpdateList).ExecuteCommandAsync();
        await repo.Context.Insertable(attInsertList).ExecuteCommandAsync();

        return main.id;
    }

    //原来老的方式 ：删除
    public async Task Deletey(string ids)
    {
        var idArr = ids.Split(",");
        await repo.Context.Deleteable<MyDemoMain>().In(idArr).ExecuteCommandAsync();
        for (int i = 0; i < idArr.Length; i++)
        {
            var mid = idArr[i];
            await repo.Context.Deleteable<MyDemoViman>().Where(it => it.mid == mid).ExecuteCommandAsync();
            await repo.Context.Deleteable<MyDemoEdman>().Where(it => it.mid == mid).ExecuteCommandAsync();
            await repo.Context.Deleteable<MyDemoItem>().Where(it => it.maiid == mid).ExecuteCommandAsync();
            await repo.Context.Deleteable<MyDemoAtt>().Where(it => it.busid == mid).ExecuteCommandAsync();
        }
    }

    //原来老的方式 ：查询
    public async Task<MyDemoMain> Selecty(String id)
    {
        var main = await SingleAsync(id);
        main.vimen = await repo.Context.Queryable<SysOrg, MyDemoViman>((o, m) => new JoinQueryInfos(
                JoinType.Inner, o.id == m.oid))
            .Where((o, m) => m.mid == id).ToListAsync();
        main.edmen = await repo.Context.Queryable<SysOrg, MyDemoEdman>((o, m) => new JoinQueryInfos(
                JoinType.Inner, o.id == m.oid))
            .Where((o, m) => m.mid == id).ToListAsync();
        if (main.opmid != null)
        {
            main.opman = await repo.Context.Queryable<SysOrg>()
                .Where(it => it.id == main.opmid).SingleAsync();
        }

        main.items = await repo.Context.Queryable<MyDemoItem>()
            .Where(it => it.maiid.Equals(id)).ToListAsync();

        main.atts = await repo.Context.Queryable<MyDemoAtt>()
            .Where(it => it.busid.Equals(id)).ToListAsync();
        return main;
    }
    
    private readonly BpmProcMainService _procService;

    public MyDemoMainService(SqlSugarRepository<MyDemoMain> repo,
        BpmProcMainService procService)
    {
        this.repo = repo;
        _procService = procService;
    }
}